#include <string>

using namespace std;

class TreeNode {
public:
    TreeNode() :
        value(""), count(1), left(nullptr), right(nullptr) { }
    TreeNode(const string s = string(), TreeNode *lchild = nullptr,
             TreeNode *rchild = nullptr) :
        value(s), count(1), left(lchild), right(rchild) { }
    TreeNode(const TreeNode &tn);
    void CopyTree();
    int ReleaseTree();
    ~TreeNode();
private:
    std::string value;
    int count;
    TreeNode *left;
    TreeNode *right;
};

class BinStrTree {
public:
    BinStrTree() :
        root(nullptr) { }
    BinStrTree(TreeNode *t = nullptr) :
        root(t) { }
    BinStrTree(const BinStrTree &rst) :
        root(rst.root) { root->CopyTree(); }    // 拷贝整棵树
    ~BinStrTree();
private:
    TreeNode *root;
};

// 拷贝以此节点为根的子树——增加引用计数
void TreeNode::CopyTree()
{
    if (left) {
        left->CopyTree();   // 左子树不空,拷贝左子树
    }
    if (right) {
        right->CopyTree();  // 右子树不空,拷贝右子树
    }
    count++;
}

// 从某个节点开始拷贝子树
TreeNode::TreeNode(const TreeNode &tn) :
    value(tn.value), count(1), left(tn.left), right(tn.right)
{
    if (left) {
        left->CopyTree();   // 左子树不空,拷贝左子树
    }
    if (right) {
        right->CopyTree();  // 右子树不空,拷贝右子树
    }
}

// 析构函数
BinStrTree::~BinStrTree()
{
    if (!root->ReleaseTree()) { // 释放整棵树,而非仅仅根节点
        delete root;            // 引用计数为 0,释放节点空间
    }
}

int TreeNode::ReleaseTree() // 释放以此节点为根的子树
{
    if (left) { // 左子树不空,释放左子树
        if (!left->CopyTree()) {
            delete left;    // 左孩子引用计数为 0,释放其空间
        }
    }
    if (right) {    // 右子树不空,释放右子树
        if (!right->CopyTree()) {
            delete right;   // 右孩子引用计数为 0,释放其空间
        }
    }
    count--;
    return count;
}

TreeNode::~TreeNode()
{
    // count 为 0 表示资源已经被释放,是 delete 函数触发的析构函数,什么也不做即可
    if (count) {
        ReleaseTree();
    }
}
